Repository navigation
refactor(metadata-protocol): generate the protocol.ts section split with a deterministic codemod - #29998
Conversation
…ith a deterministic codemod (WIP) scripts/codemod-split-protocol.mjs applies the E1 host split (packages/metadata-protocol/scripts/host-split.mjs) to whole sections of ObjectStackProtocolImplementation and proves the move: undoing it rebuilds the base protocol.ts and protocol-host.ts byte for byte, and host-split's own check passes for every moved member. Generated output, unedited. Claude-Session: https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz Co-Authored-By: Claude <noreply@anthropic.com>
…e import prune
The codemod now drops the imports only the moved bodies read (the package
compiles with noUnusedLocals), and its byte-identity proof recomputes that
prune from the head's own references. A JSDoc {@link X} counts as a read, as
the compiler counts it. A move that would reach a type-predicate method
through a new host entry stays (the forwarding closure drops the predicate).
An inferred return type no longer keeps a method in protocol.ts.
Regenerated: 70/284 methods move into 10 section modules; protocol.ts goes
from 23135 to 13905 lines.
Claude-Session: https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz
Co-Authored-By: Claude <noreply@anthropic.com>
…er in protocol.ts A moved body that reads no member would never read its `host` parameter, which the package's noUnusedParameters refuses, so such a method now stays (stay rule no-host-read). Regenerated: 69/284 methods move; protocol.ts goes from 23135 to 13915 lines. Claude-Session: https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz Co-Authored-By: Claude <noreply@anthropic.com>
… in protocol.ts and widen the by-path censuses The declaration bar on the built .d.ts refused the previous split: moving getDiscovery's body made the compiler re-infer its printed return type through the moved function, which dropped the @deprecated docblock on one key. The pilot's rule is back: a non-private method with an inferred return type stays. Regenerated: 61/284 methods move into 9 section modules; protocol.ts goes from 23135 to 15318 lines. The censuses that read protocol.ts by path now also read the modules the split moved bodies to, where the class is spelled host. instead of this. (ruling 6597555122): the recovery-door emit and projector counts, the write-through and registerItem caller sets, the lookupArtifactItem sites, the read-verb fold population (the signature is read off the class member, the fold off the moved body) and the stored-row write census of the view expansion reconcile. Claude-Session: https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz Co-Authored-By: Claude <noreply@anthropic.com>
…verned bodies The split moved the bodies the protocol.ts entry's invariants govern: applyObjectRegistryMutation and hydrateOverlayIntoRegistry into protocol-registry-hydration.ts, loadMetaFromDb into protocol-diff-delete-load.ts, saveMetaItem's view storage into protocol-save.ts. Each module gets an entry carrying the host entry's own invariant paragraphs for the ADRs it now cites (ADR-0029 and ADR-0126, ADR-0029, ADR-0005 and ADR-0087), as the sql-driver pilot did; the host entry stays for the stubs and the citations left there. Claude-Session: https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz Co-Authored-By: Claude <noreply@anthropic.com>
…lity census; parse through ts-parse check-durability-degradation-log-level read three moved catch blocks as inventing an answer, lost one read seam, and kept two stale FAILURE_PROPAGATION_SITES keys, all because the codemod split moved the bodies into section modules: - A moved body that delegates its catch to the class's guard as host.rethrowUnlessMetadataStoreUnprovisioned(error) now reaches that guard through the same HOST CALL rule isReadCall already follows. - A host.x() call resolves to the class member x first, through its stub, even when the module declares x itself (x's own moved body, whose extra host parameter failed the arity check). This restores rollbackToPackageCommit's seam around revertCommit. - migrateStoredMetadata and duplicatePackage are keyed by their new modules. The census reads the base's numbers again: 51 durability seams (9 propagating), 102 read seams (13 discriminated). Three self-test rows pin the two rules (the read-seam floor goes 67 -> 70); removing either rule turns exactly its row red. The codemod now parses through ts-parse.mjs (parseSourceFile, createProgramChecked), as check:parse-guard requires. Claude-Session: https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz Co-Authored-By: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 75 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 18 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 10 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 4d3ca895e003361790ddd7450a82b320371da644 && git checkout 4d3ca895e003361790ddd7450a82b320371da644
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 63b86b385dd2cbfeba131438112c49be2c74df91 bba9d24d79853f4ae24a0991d6faba94aa06a02c && git checkout -B drift-repro 63b86b385dd2cbfeba131438112c49be2c74df91 && git merge --no-ff bba9d24d79853f4ae24a0991d6faba94aa06a02c
node scripts/docs-audit/affected-docs.mjs --json 63b86b385dd2cbfeba131438112c49be2c74df91
|
Regenerate the split on the latest main; main has not changed protocol.ts or protocol-host.ts since 9049be2. Claude-Session: https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz Co-Authored-By: Claude <noreply@anthropic.com>
… form Lift the codemod's output into the facade form of ruling 6624345766: each section module becomes one stateless facet class whose static methods take the host, every moved member on ObjectStackProtocolImplementation delegates to its facet in one line, a private member's docblock moves with its body, and pure private statics move too. The pilot's no-yield rule is dropped (the facade keeps delegations only). verify unlifts the head back to the module form and proves it against the base as before. The by-path readers and the durability census follow the facet form. Claude-Session: https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz Co-Authored-By: Claude <noreply@anthropic.com>
|
domain:server#6 · os-support-ai · session_01WGufzibcN9oHa8kDbTTnL5 席位核对Verdict: ACCEPT at head
|
Requested by Yibo Wang · project thread
Part of #29985
维护者速读
scripts/codemod-split-protocol.mjs按裁决 6624345766(门面形态,方案 A)生成protocol.ts的拆分。ObjectStackProtocolImplementation成为门面:85 个成员各留一行委派,方法体移入 10 个无状态 facet 类(<Module>Facet,静态方法,首参是 host);私有成员的文档块随方法体移走(54 个),公开成员的文档块留在门面;只读参数的私有静态方法也移出(7 个)。状态全部留在门面。生成文件未手改。.d.ts门槛改为「公开面相等」。--verify先把门面形态逆提回 (a) 的模块形态,再逆推出 base 的protocol.ts和protocol-host.ts逐字节相同。公开面.d.ts相等(对照抓到)。测试 base 22,346 → head 22,347(+1 条非空检查)。回滚即 revert。lift/unlift;③check-durability-degradation-log-level.mjs对<X>Facet.fn(...)存根的跟随和 3 条自测。pnpm install --frozen-lockfile后运行node scripts/codemod-split-protocol.mjs --verify --base eee41490,预期85/85 moved bodies restore to the base body exactly、23135 -> 13647 lines,退出码 0;--self-test55 例通过。protocol.ts后落地;本 PR 保持草稿。Clause-②: no
Metadata-protocol: none
What changes
scripts/codemod-split-protocol.mjs, three additions over the module form PR refactor(metadata-protocol): generate the protocol.ts section split with a deterministic codemod #29998 had before:lift, ruling 6624345766). Each section module's functions become the static methods of one stateless facet class,<Module>Facet(protocol-save.ts→ProtocolSaveFacet). A method still takes the host as its first parameter, so its body is the E1 body re-indented back to the class's depth. A facet holds no state: every field stays on the class and is read through the host. Each stub on the class calls<Facet>.<member>(…)./** Docblock and body: {@link <Facet>.<member>} in \` [Codemod split: generate the rest of the metadata-protocol protocol.ts split with a deterministic script, verified byte-identical #29985 codemod]. */. A public member's docblock stays on the facade, as the ruling requires, so the published.d.ts` and consumers' hover text are unchanged.this,super,argumentsor class name) moves to its section's facet with no host parameter. The class keeps the delegation, so moved instance bodies still reach it ashost.<static>.no-yieldrule (a body no longer than its stub stays) is dropped: under the facade rule the class keeps delegations only.unlift).--verifyreads the head alone, turns it back into the module form, and refuses anything the lift would not have written: a public docblock moved, a stub calling another facet, a facet member that is not a static method, a body line the lift did not indent. It then runs every earlier proof on that module form,host-split.mjs'scheckMoveincluded.--self-test: 55 cases in 7 pinned batteries (a newfacade layerbattery of 10).--writeonmaineee41490, unedited. Its modules areprotocol-class-head.ts,protocol-discovery-and-bases.ts,protocol-data-crud.ts(new),protocol-search-and-cache.ts,protocol-write-gates.ts,protocol-registry-hydration.ts,protocol-save.ts,protocol-history-and-publish.ts,protocol-package-commits.tsandprotocol-diff-delete-load.ts. Nothing re-exports them.register-item,lookup-artifact-itemandview-expansion-reconcilecensus headers accept a facet'sstaticmember.read-verb-canonical-foldfollows<Facet>.<fn>stubs.applyRemoteMetadataMutationas a static method.isShippedByAnotherPackagegets afilerow.anotherPackageShipsis read as its delegation plus its facet body.scripts/check-durability-degradation-log-level.mjs: a<X>Facet.fn(protocolHost(this), …)stub, or a private static's<X>Facet.fn(…), is followed into the facet's static method. Without that, 3 read seams left the census (102 → 99). There are three new self-test rows, and the read-seam floor goes 70 → 73.Verification
eee41490protocol.tslinescheckMove78/78 instance (statics compared directly); the unlift, then the undo, rebuilds both base files85bbdf726e8fbb750229627f744bb152aa79fcfa02d95b939885bbdf3430fe92on two runs; regeneration reproduces the committed treemetadata-protocoltypecheckmetadata-protocoltestcheck:durability-log-leveltest:repo,pnpm lint,pnpm builddispatch-gates --commands(73)--ran: 0 NOT-MEASURED, 0 UNRUN.d.ts: ruling 6624345766 item 1, "public surface EQUAL"The reading is
dts-public.mjs, in the project files atissue-29985/dts-public.mjs, sha256211b32062250606e658acd7fb8880e0079b4043121fb7b970c658b4b57bf5020. It is dtsnorm (6441032442 B) with one step added first: every private class member, together with its docblock, is cut from both texts. Everything else must then be equal statement for statement, which is stricter than item 1.index.d.tsindex.d.cts.d.ts.Facade reading (the #30019 gate's starting allow-list)
85 members delegate to 10 facets:
190 hand-series delegations in their own forms:
.call(host, …)162, plain 12,protocolHost(this)16. Their docblocks stay on the class, because their modules are the hand series' and are not facets.26 methods with a body stay as named exceptions, plus the constructor (15 lines) and the static block (the host factory, 203 lines):
inferred-return-type(a public type the.d.tswould re-infer):getDiscovery460 lines,findData751,getData75,cloneData105, andsaveMetaItem,publishMetaItem,rollbackMetaItem,deleteMetaItemat 7 lines each.closed-set(outside E1's rewrite set):publishPackageDrafts993 lines (a barethis),reconcileViewExpansions53,packagelessOverlayWriteRefusal14,namedBaseOverlayWriteRefusal12.static-reads-class:mergesOverlayAtRead,registryAllowsOverlay,isOverlayAllowed,isRuntimeCreateAllowed,codeOnlySourceHint,codeOnlyCreateError,codeOnlyOverrideError,refuseOrganizationScopedWrite,overlayPackageMismatchError.no-host-read:rethrowUnlessMetadataStoreUnprovisioned,triggerAutomation.name-taken:objectExtensionItemRefusal.host-entry-predicate:packagedBaseRefusal.static-shape(public static):resetEnvWritableCache.Ablations
unlift's public-docblock check is removed.Findings outside this PR
protocol-packageless-overlay-migration.tsis #30000; it is unchanged here.🤖 Generated with Claude Code
https://claude.ai/code/session_01WGufzgddMBbTQd9yVo4Yuz